<?php
/**
 * @author  sandeep
 */
 
class MailParser
{
    private $_hasAttachment = 0;
    
    public function parseMail(Zend_Mail_Message $messageObject, $uid)
    {
        $this->_hasAttachment = 0;
    	$message = array();
        $message['flags'] = key($messageObject->getFlags());
        $headers = $messageObject->getHeaders();
        $message['to'] = $headers['to'];
        $message['returnPath']  = (array_key_exists('return-path', $headers)) ? $headers['return-path'] : '';
        $message['date'] = strtotime($this->_getDate($headers));
        $message['from'] = $headers['from'];
        $message['contentType'] = @$headers['content-type'];
        $message['uid'] = $uid;
        $message['subject'] = @$headers['subject'];
        $message['contentTransferEncoding'] = array_key_exists('content-transfer-encoding',$headers) ?
                                                              $headers['content-transfer-encoding'] : null;
        if ($messageObject->countParts() == 0) {
            $message['content'] = $messageObject->getContent();
        } else {
            $message['parts'] = $this->getParts($messageObject, $messageObject->countParts());
        }
        $message['attachment'] = $this->_hasAttachment;
        return $message;
    }
    
    public function getParts($message, $maxParts)
    {
        $parts = array();
        for ($i = 1; $i <= $maxParts; $i++) {
        $part = $message->getPart($i);
        $headers = $this->parsePartHeaders($part->getHeaders());
            foreach ($headers as $key => $value) {
                $parts[$i][$key] = $value;
        }
        if($part->isMultipart()) {
            $childCount = $part->countParts();
            $parts[$i]['parts'] = $this->getParts($part, $childCount);                    
        } else {
            $parts[$i]['content'] = $this->parseContent($part->getContent(), @$parts[$i]['content-transfer-encoding']);
            $parts[$i]['size'] = $part->getSize();
        }
        }
        return $parts;
    }
    
    public function getAttachment($message, $attachmentId)
    {
        //$Iterator = new ArrayIterator($message['parts']);
        //Zend_Debug::dump($Iterator);
        $this->findAttachment($message['parts'], $attachmentId);
    }
    
    public function findAttachment($array, $key)
    {
        foreach ($array as $n => $v)
        {
            if (is_array($v)) {
                $this->findAttachment($v, $key);
            } elseif ($v == $key) {
                header('Content-Type: '.$array['type'].'');
                header("Content-Disposition: attachment; filename=\"".@$array['filename']."\"");
                echo $array['content']; exit; 
            }
        }
    }
    
    public function parsePartHeaders($headers)
    {
        if (array_key_exists('content-disposition',$headers)) {
            $temp = explode(';', $headers['content-disposition']);
            $headers['content-disposition'] = $temp[0];
            //Zend_Debug::dump($temp[0]);
            if ($temp[0] == 'attachment') {
                var_dump($temp);
            	$this->_hasAttachment = 1;
            }
            $temp = explode('"',$temp[1]);
            //$headers['filename'] = $temp[1];
        }
        if (array_key_exists('content-type',$headers)) {
            $temp = explode(';', $headers['content-type']);
            @$headers['type'] = $temp[0];
            $temp = explode('"', @$temp[1]);
            if (trim($temp[0]) == "name=") {
                $headers['filename'] = $temp[1];
            } 
        }
        return $headers;
    }
    
    public function parseContent($content, $encoding)
    {
        switch (strtolower($encoding)) {
            case '7bit':
                return $content;
                break;

            case 'quoted-printable':
                return utf8_encode($this->_quotedPrintableDecode($content));
                break;

            case 'base64':
                return base64_decode($content);
                break;

            default:
                return $content;
        }
    }
    
    private function _getDate($headers)
    {
        if (array_key_exists('received', $headers)) {
            if(is_array($headers['received'])) {
                $received = $headers['received'][0];
                $date = explode(';',$received);
            } else {
                $received = $headers['received'];
                $date = explode(';',$received);
            }
            return $date[1];               
        }  else {
            $date = $headers['date'];
            return $date;
        }
    }
    
    private function _quotedPrintableDecode($input)
    {
        // Remove soft line breaks
        $input = preg_replace("/=\r?\n/", '', $input);
        //$input = preg_replace('/=A0/','&nbsp',$input);
        // Replace encoded characters
		$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input);
        return $input;
    }
    
    public function cleanContent($source)
    {
       // Handle BASE Tags so they do not screw up our tags
       
       
       // Hammer other special characters
       $source = preg_replace('/(&ndash;|&rsquo;|&rdquo;|&reg;|&nbsp;)/', '', $source );
       return $source;
    }

    
}